package com.borko.healthcare.tapestry.pages;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.tapestry5.PersistenceConstants;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.InjectPage;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.services.Cookies;
import org.springframework.context.ApplicationContext;

import com.borko.healthcare.entities.beans.MedicineOrderBean;
import com.borko.healthcare.entities.beans.NotificationBean;
import com.borko.healthcare.entities.beans.OrderBean;
import com.borko.healthcare.entities.interfaces.Medicine;
import com.borko.healthcare.entities.interfaces.MedicineOrder;
import com.borko.healthcare.entities.interfaces.Notification;
import com.borko.healthcare.entities.interfaces.Order;
import com.borko.healthcare.entities.interfaces.Pharmacist;
import com.borko.healthcare.entities.interfaces.Supplier;
import com.borko.healthcare.persistence.hibernate.services.MedicineOrderManager;
import com.borko.healthcare.persistence.hibernate.services.NotificationManager;
import com.borko.healthcare.persistence.hibernate.services.OrderManager;
import com.borko.healthcare.persistence.hibernate.services.PharmacistManager;
import com.borko.healthcare.persistence.hibernate.services.SupplierManager;
import com.borko.healthcare.utils.beans.CartBean;
import com.borko.healthcare.utils.interfaces.Cart;

public class OrderMedicines {
	
	@Inject
	private Cookies cookies;
	
	@SuppressWarnings("unused")
	@Inject
	private Messages messages;
	
	@InjectComponent
	private Zone medicinesZone;
	
	@InjectComponent
	@Property
	private Zone cartZone;
	
	@SuppressWarnings("unused")
	@Property
	private MedicineOrder cartMedicineOrder;
	
	@Property
	@Persist
	private Cart cart;
	
	@Inject
	private ApplicationContext applicationContext;
	
	private SupplierManager supplierManager;
	private PharmacistManager pharmacistManager;
	private OrderManager orderManager;
	private MedicineOrderManager medicineOrderManager;
	private NotificationManager notificationManager;
	
	@Property
	@Persist
	private String supplierDescriptor;
	
	@SuppressWarnings("unused")
	@Property
	@Persist(PersistenceConstants.FLASH)
	private MedicineOrder medicineOrder;
	
	@Persist
	private List<MedicineOrder> medicineOrders;
	
	@Persist
	private Map<Integer, List<MedicineOrder>> cashe;
	
	@Persist
	private Order order;
	
	private int counter;
	
	@InjectPage
	private OrderReview orderReview;
	
	@SetupRender
	public void initialize() {
		if (cashe == null) {
			cashe = new HashMap<Integer, List<MedicineOrder>>();
		}
		
		if (cart == null) {
			cart = new CartBean();
		}
		
		if (order == null) {
			order = new OrderBean();
		}
		
		counter = 0;
	}
	
	public List<MedicineOrder> getCartMedicineOrders() {
		return cart.getMedicineOrders();
	}
	
	public Object onValueChangedFromSupplierDescriptor(String supplierDescriptor) {
		int id = Integer.parseInt(supplierDescriptor);
		if (id < 0) {
			return null;
		}
		if (cashe.get(id) == null) {
			supplierManager = (SupplierManager) applicationContext.getBean("supplierManager");
			Supplier supplier = supplierManager.getSupplier(id);
			List<Medicine> medicines = supplier.getMedicines();
				
			medicineOrders = new ArrayList<MedicineOrder>();
			for (Medicine medicine : medicines) {
				MedicineOrder medicineOrder = new MedicineOrderBean();
				medicineOrder.setMedicine(medicine);
				medicineOrder.getMedicine().setSupplier(supplier);
					
				medicineOrders.add(medicineOrder);
			}
			
			cashe.put(id, medicineOrders);
		} else {
			medicineOrders = cashe.get(id);
		}
		
		return medicinesZone.getBody();
    }
	
	public List<MedicineOrder> getMedicineOrders() {
		if (cashe.get(Integer.parseInt(supplierDescriptor)) != null) {
			return cashe.get(Integer.parseInt(supplierDescriptor));
		}
		
		return medicineOrders;
	}
	
	/**
	 * Used for populating select component with items
	 * @return formated string output. Example: "1=Jovica Jovic, 2=Perica Peric".
	 */
	public String getSuppliers() {
		supplierManager = (SupplierManager) applicationContext.getBean("supplierManager");
		List<Supplier> suppliers = supplierManager.list();
		StringBuffer buffer = new StringBuffer();
		buffer.append("-1=Please select supplier,");
		for (Supplier supplier : suppliers) {
			buffer.append(supplier.getId() + "=");
			buffer.append(supplier.getUserDetails().getFullName() + ",");
		}
		String outputString = buffer.toString();
		if (suppliers.size() > 0) {
			outputString = outputString.substring(0, outputString.length() - 2);
		}
		return outputString;
	}
	
	public Object onActionFromDeleteFromCart(long orderNumber) {
		MedicineOrder medicineOrder = null;
		for (MedicineOrder temp : getMedicineOrders()) {
			if (temp.getOrderNumber() == orderNumber) {
				medicineOrder = temp;
				break;
			}
		}
		cart.remove(medicineOrder);
		
		return (Object)cartZone;
	}

	public MedicineOrder getNextMedicineOrder() {
		MedicineOrder medicineOrder = getMedicineOrders().get(counter++);
		if (counter >= getMedicineOrders().size()) {
			counter = 0;
		}
		return medicineOrder;
	}
	
	public Object onSuccessFromCartForm() {
		pharmacistManager = (PharmacistManager) applicationContext.getBean("pharmacistManager");
		Pharmacist pharmacist =  pharmacistManager.getPharmacist(Integer.parseInt(cookies.readCookieValue("userId")));
		
		order.setPharmacist(pharmacist);
		order.setMedicineOrders(cart.getMedicineOrders());
		order.setPrice(cart.getTotalPrice());
		
		orderManager = (OrderManager) applicationContext.getBean("orderManager");
		orderManager.add(order); // Persist order
		
		medicineOrderManager = (MedicineOrderManager) applicationContext.getBean("medicineOrderManager");
		for(MedicineOrder medicineOrder : cart.getMedicineOrders()) { // Persist medicine orders
			medicineOrder.setOrder(order);
			medicineOrderManager.add(medicineOrder);
		}
		
		List<Notification> notifications = new ArrayList<Notification>();
		
		List<Supplier> suppliers = new ArrayList<Supplier>();
		for (MedicineOrder medicineOrder : order.getMedicineOrders()) {
			Supplier supplier = medicineOrder.getMedicine().getSupplier();
			if (! suppliers.contains(supplier)) {
				suppliers.add(supplier);
				Notification notification = new NotificationBean();
				notification.setSupplier(supplier);
				notifications.add(notification);
			}
			
			for (Notification notification : notifications) {
				if (notification.getSupplier().equals(supplier)) {
					notification.getMedicineOrders().add(medicineOrder);
					notification.setPharmacist(pharmacist);
				}
			}
		}
		
		notificationManager = (NotificationManager) applicationContext.getBean("notificationManager");
		for (Notification notification : notifications) { // persist notifications
			notificationManager.add(notification);
		}
		
		orderReview.setOrder(order);
		return orderReview;
	}
}
